package wykop.analyze;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.hibernate.Session;

import wykop.page.WykopComment;
import wykop.parser.HibernateUtil;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.CharStreams;

public class CreateArffFile {

	private static final List<ICommentFeature> FEATURES = Arrays.asList(
			new CapitalLetters(), new CommentCharLength(), new CommentPlace(),
			new CommentWordLength(), new NumberOfReferences(),
			new NumberOfSubstrings(",",
					"COMMA"),
			new NumberOfTokens("pis"), new NumberOfSubstrings("wrocław",
					"wrocław"), new NumberOfSubstrings(":)", "smiley1"),
			new NumberOfSubstrings(";)", "smiley2"), new NumberOfPoints(),
			new CommentScore(-2, 3));

	public static void writer(final int j, AnalyzeConfiguration ac) throws IOException {

		final Session session = HibernateUtil.getSessionFactory()
				.getCurrentSession();
		session.beginTransaction();
		final List<WykopComment> comments = session.createCriteria(
				WykopComment.class).list();
		final Bigrams bigrams = Bigrams.create(0.0000000001);
		session.close();
		
		Set<String> wulgaryzmy = readFile( ac.wulgazryzmy );
		Set<String> spojniki = readFile( ac.wulgazryzmy );
		
		final List<ICommentFeature> thisFeatures = Lists.newArrayList(FEATURES);
		thisFeatures.add(0, new NumberOfTokens("wulgaryzmy", wulgaryzmy));
		thisFeatures.add(0, new NumberOfTokens("spojniki", spojniki));
		thisFeatures.add(0, new ViterbiScore(bigrams));
		
		final BufferedWriter writer = new BufferedWriter(new FileWriter("file"
				+ j + ".arff"));
		writer.append("@RELATION wykop");
		writer.newLine();

		
		

		for (final ICommentFeature feature : thisFeatures) {
			writer.append("@ATTRIBUTE " + feature.name() + " " + feature.type());
			writer.newLine();
		}

		writer.newLine();
		writer.append("@Data");
		writer.newLine();

		for (final WykopComment comment : comments) {
			for (int i = 0; i < thisFeatures.size(); i++) {
				final ICommentFeature feature = thisFeatures.get(i);
				writer.append(feature.forComment(comment));
				if (i != thisFeatures.size() - 1) {
					writer.append(",");
				}
			}
			writer.newLine();
			writer.flush();
		}

		writer.close();
	}
	
	private static Set<String> readFile(String path)
	{
		InputStream is = CreateArffFile.class.getResourceAsStream(path);
		try {
			List<String> lines = CharStreams.readLines( new InputStreamReader(is) );
			return Sets.newHashSet( lines ); 
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		
	}

	public static Runnable startLogging(final AnalyzeConfiguration ac) {
		final AtomicInteger ai = new AtomicInteger(0);

		return new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						final Object o = new Object();
						synchronized (o) {
							final int i = ai.incrementAndGet();
							CreateArffFile.writer(i,ac);
							o.wait(ac.arffWait);
						}
					} catch (final Exception e) {
						throw new RuntimeException(e);
					}
				}

			}

		};

	}

}
